<Project DefaultTargets="Build">
  <Import Project="Common\dirs.proj" />
  <Import Project="Directory.Build.targets" />
  <Import Project="xunit-wrappers.targets" />

  <Import Project="$(MonoProjectRoot)\msbuild\apple\build\AppleBuild.props" />
  <Import Project="$(MonoProjectRoot)\msbuild\apple\build\AppleBuild.InTree.targets" />

  <PropertyGroup>
    <XunitTestBinBase Condition="'$(XunitTestBinBase)'==''" >$(BaseOutputPathWithConfig)</XunitTestBinBase>
    <XunitWrapperGeneratedCSDirBase>$(XunitTestBinBase)\TestWrappers\</XunitWrapperGeneratedCSDirBase>
    <MSBuildEnableAllPropertyFunctions>1</MSBuildEnableAllPropertyFunctions>
    <Language>C#</Language>
    <RuntimeIdentifier>$(OutputRID)</RuntimeIdentifier>
  </PropertyGroup>

  <ItemGroup>
    <DisabledTestDir Include="bin" />
    <DisabledTestDir Include="Common" />
    <DisabledTestDir Include="Tests" />
    <DisabledTestDir Include="TestWrappers" />
  </ItemGroup>

  <ItemGroup>
    <RestoreProjects Include="Common\test_dependencies_fs\test_dependencies.fsproj" />
    <RestoreProjects Include="Common\test_dependencies\test_dependencies.csproj" />
    <RestoreProjects Include="Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj" />
    <RestoreProjects Include="Common\GenerateHWIntrinsicTests\GenerateHWIntrinsicTests_Arm.csproj" />
    <RestoreProjects Include="Common\GenerateHWIntrinsicTests\GenerateHWIntrinsicTests_General.csproj" />
    <RestoreProjects Include="Common\GenerateHWIntrinsicTests\GenerateHWIntrinsicTests_X86.csproj" />
    <RestoreProjects Include="Common\XUnitLogChecker\XUnitLogChecker.csproj" />
    <RestoreProjects Include="Common\XUnitWrapperGenerator\XUnitWrapperGenerator.csproj" />
    <RestoreProjects Include="Common\XUnitWrapperLibrary\XUnitWrapperLibrary.csproj" />
    <RestoreProjects Include="Common\XHarnessRunnerLibrary\XHarnessRunnerLibrary.csproj" />
    <RestoreProjects Include="Common\external\external.csproj" />
    <RestoreProjects Include="Common\ilasm\ilasm.ilproj" />
  </ItemGroup>

  <ItemGroup>
    <TestBuildSteps Include="RestorePackages" />
    <TestBuildSteps Include="ManagedBuild" />
    <TestBuildSteps Include="CheckTestBuildStep" />
    <TestBuildSteps Include="GenerateLayout" />
    <TestBuildSteps Include="BuildTestWrappers" />
    <TestBuildSteps Include="CrossgenFramework" />
    <TestBuildSteps Include="CreateAndroidApps" />
    <TestBuildSteps Include="CreateIosApps" />
    <TestBuildSteps Include="BuildMonoAot" />
  </ItemGroup>

  <Target Name="Rebuild" />

  <Target Name="FindCmdDirectories" DependsOnTargets="GetListOfTestCmds">

    <Error Condition="!Exists('$(XunitTestBinBase)')"
           Text="$(XunitTestBinBase) does not exist. Please run src\tests\build / src/tests/build.sh from the repo root at least once to get the tests built." />

    <ItemGroup Condition="'@(LegacyRunnableTestPaths)' != ''">
      <LegacyRunnableTestPaths Separator="$([System.String]::Copy('%(LegacyRunnableTestPaths.Identity)').IndexOfAny('\\/', $(XunitTestBinBase.Length)))" />
      <LegacyRunnableTestPaths SecondSeparator="$([System.String]::Copy('%(LegacyRunnableTestPaths.Identity)').IndexOfAny('\\/', $([MSBuild]::Add(%(LegacyRunnableTestPaths.Separator), 1))))" />
      <LegacyRunnableTestPaths ThirdSeparator="$([System.String]::Copy('%(LegacyRunnableTestPaths.Identity)').IndexOfAny('\\/', $([MSBuild]::Add(%(LegacyRunnableTestPaths.SecondSeparator), 1))))" />
      <LegacyRunnableTestPaths Separator="%(LegacyRunnableTestPaths.SecondSeparator)" Condition="'%(LegacyRunnableTestPaths.SecondSeparator)' != '-1'" />
      <LegacyRunnableTestPaths Separator="%(LegacyRunnableTestPaths.ThirdSeparator)" Condition="'%(LegacyRunnableTestPaths.ThirdSeparator)' != '-1' and '$(TestBuildMode)' == 'nativeaot' and '$(TargetsAppleMobile)' == 'true'" />
      <TestDirectoriesWithDup Include="$([System.String]::Copy('%(LegacyRunnableTestPaths.Identity)').Substring(0, %(LegacyRunnableTestPaths.Separator)))" />
    </ItemGroup>

    <RemoveDuplicates Inputs="@(TestDirectoriesWithDup)">
      <Output
          TaskParameter="Filtered"
          ItemName="TestDirectories"/>
    </RemoveDuplicates>

  </Target>

  <!-- Target to check the test build, to see if it looks ok. We've had several cases where a change inadvertently and drastically changes
       the set of tests that are built, and that change is unnoticed. The most common case is for a build of the Priority 1 tests
       to only build the Priority 0 tests. This target is run after a test build to verify that the basic number of tests that were
       built is basically what was expected. When this was written, there were about 2500 Priority 0 tests and about 10268 Priority 1
       tests on Windows, 9976 on Ubuntu (it differs slightly based on platform). We currently check that the number of Priority 0 tests
       is greater than 2000 and less than 3000, and the number of Priority 1 tests is greater than 9000.
  -->
  <Target Name="CheckTestBuild" DependsOnTargets="GetListOfTestCmds">
    <Error Condition="!Exists('$(XunitTestBinBase)')"
        Text="$(XunitTestBinBase) does not exist. Please run src\tests\build / src/tests/build.sh from the repo root at least once to get the tests built." />

    <PropertyGroup>
        <TestCount>@(LegacyRunnableTestPaths->Count())</TestCount>
    </PropertyGroup>

    <Message Text="Found $(TestCount) built tests"/>

    <ItemGroup>
      <Error Condition="'$(CLRTestPriorityToBuild)' == '0' and '$(TestCount)' &lt;= 2000" Text="Unexpected test count. Expected &gt; 2000, found $(TestCount).'" />
      <Error Condition="'$(CLRTestPriorityToBuild)' == '0' and '$(TestCount)' &gt;= 3000" Text="Unexpected test count. Expected &lt; 3000, found $(TestCount).'" />
      <Error Condition="'$(CLRTestPriorityToBuild)' == '1' and '$(TestCount)' &lt;= 9000" Text="Unexpected test count. Expected &gt; 9000, found $(TestCount).'" />
      <Error Condition="'$(CLRTestPriorityToBuild)' != '0' and '$(CLRTestPriorityToBuild)' != '1'" Text="Unknown priority $(CLRTestPriorityToBuild)" />
    </ItemGroup>
  </Target>

  <Import Project="$(__Exclude)" Condition="'$(__Exclude)' != '' AND '$(XunitTestBinBase)' != ''" />
  <PropertyGroup>
    <HaveExcludes>False</HaveExcludes>
    <HaveExcludes Condition="'$(__Exclude)' != ''">True</HaveExcludes>
  </PropertyGroup>

  <Target Name="MonoAotCompileTests" DependsOnTargets="GetListOfTestCmds;FindCmdDirectories">
    <ItemGroup>
      <AllTestScripts Condition="'@(TestDirectories)' != ''" Include="%(TestDirectories.Identity)\**\*.sh" />
      <AllTestScripts Condition="'@(MergedRunnableTestPaths)' != ''" Include="%(MergedRunnableTestPaths.RootDir)%(MergedRunnableTestPaths.Directory)*.dll" />
      <AllTestScripts Condition="'@(OutOfProcessTestPaths)' != ''" Include="%(OutOfProcessTestPaths.RootDir)%(OutOfProcessTestPaths.Directory)*.sh" />
      <TestExclusions Include="@(ExcludeList->Metadata('FullPath'))" Condition="$(HaveExcludes)" />
      <TestScripts Include="@(AllTestScripts)" Exclude="@(TestExclusions)" />

      <TestAssemblyPaths Include="$([System.IO.Path]::ChangeExtension('%(TestScripts.Identity)', 'dll'))" />
      <TestAssemblies Include="%(TestAssemblyPaths.Identity)" Condition="Exists(%(TestAssemblyPaths.Identity))" />
      <TestDirsWithDuplicates Include="$([System.IO.Path]::GetDirectoryName('%(TestAssemblies.Identity)'))" />
    </ItemGroup>
      
    <Error 
      Text="No tests found for Mono AOT compilation. Make sure that the desired test cases are not excluded from AOT compilation."
      Condition="!Exists(%(TestAssemblies.Identity))" />

    <RemoveDuplicates Inputs="@(TestDirsWithDuplicates)">
      <Output TaskParameter="Filtered" ItemName="TestDirs" />
    </RemoveDuplicates>
    <ItemGroup>  
      <TestsAndAssociatedAssemblies Include="%(TestDirs.Identity)/**/*.dll" Exclude="@(NoMonoAotAssemblyPaths)" />
      <CoreRootDlls Include="$(CORE_ROOT)/*.dll" Exclude="$(CORE_ROOT)/xunit.performance.api.dll;$(CORE_ROOT)/Microsoft.CodeAnalysis.VisualBasic.dll" />
      <AllDlls Condition="'$(MonoFullAot)' == 'true'" Include="@(TestsAndAssociatedAssemblies);@(CoreRootDlls)" />
      <AllDlls Condition="'$(MonoFullAot)' != 'true'" Include="@(TestsAndAssociatedAssemblies)" />
    </ItemGroup>

    <PropertyGroup Condition="'$(CROSSCOMPILE)' == ''">
      <AotCompiler Condition="'$(RunningOnUnix)' == 'true'">$(CORE_ROOT)/corerun</AotCompiler>
      <AotCompiler Condition="'$(RunningOnUnix)' != 'true'">$(CORE_ROOT)\corerun.exe</AotCompiler>
      <MonoLlvmPath>$(MonoBinDir)</MonoLlvmPath>
    </PropertyGroup>
    <PropertyGroup Condition="'$(CROSSCOMPILE)' != ''">
      <AotCompiler>$(MonoBinDir)/cross/$(OutputRID)/mono-aot-cross</AotCompiler>
      <MonoLlvmPath>$(MonoBinDir)/cross/$(OutputRID)</MonoLlvmPath>
    </PropertyGroup>

    <ItemGroup>
      <MonoAotOption Condition="'$(MonoForceInterpreter)' == 'true'" Include="interp" />
      <MonoAotOption Condition="'$(MonoFullAot)' == 'true'" Include="full" />
      <MonoAotOption Condition="'$(MonoFullAot)' == 'true'" Include="nimt-trampolines=2000" />
      <MonoAotOption Condition="'$(MonoFullAot)' == 'true'" Include="ntrampolines=20000" />
      <MonoAotOption Condition="'$(MonoFullAot)' == 'true'" Include="nrgctx-fetch-trampolines=256" />
      <MonoAotOption Condition="'$(MonoFullAot)' == 'true'" Include="ngsharedvt-trampolines=8400" />
      <MonoAotOption Condition="'$(MonoFullAot)' == 'true'" Include="nftnptr-arg-trampolines=4000" />
      <MonoAotOption Condition="'$(MonoFullAot)' == 'true'" Include="nrgctx-trampolines=21000" />
      <MonoAotOption Include="llvm" />
      <MonoAotOption Include="llvm-path=$(MonoLlvmPath)" />
      <MonoAotOption Condition="'$(__MonoToolPrefix)' != ''" Include="tool-prefix=$(__MonoToolPrefix)" />
    </ItemGroup>
    <ItemGroup Condition="'$(TargetArchitecture)' == 'arm64'">
      <MonoAotOption Include="mattr=crc" />
      <MonoAotOption Include="mattr=crypto" />
    </ItemGroup>
    <ItemGroup Condition="'$(TargetArchitecture)' == 'x64'">
      <MonoAotOption Include="mattr=sse4.2" />
      <MonoAotOption Include="mattr=popcnt" />
      <MonoAotOption Include="mattr=lzcnt" />
      <MonoAotOption Include="mattr=bmi" />
      <MonoAotOption Include="mattr=bmi2" />
      <MonoAotOption Include="mattr=pclmul" />
      <MonoAotOption Include="mattr=aes" />
    </ItemGroup>
    <PropertyGroup>
      <MonoAotOptions>@(MonoAotOption->'%(Identity)', ',')</MonoAotOptions>
      <MonoPath>$(CORE_ROOT)</MonoPath>
    </PropertyGroup>

    <Message Importance="High" Text="Mono AOT options: $(MonoAotOptions)" />
    <Message Importance="High" Text="Mono AOT MONO_PATH: $(MonoPath)" />

    <ItemGroup>
      <AotProject Include="../mono/msbuild/aot-compile.proj">
        <Properties>_AotCompiler=$(AotCompiler);_TestDll=%(AllDlls.Identity);_MonoPath=$(MonoPath);_MonoAotOptions=$(MonoAotOptions)</Properties>
      </AotProject>
    </ItemGroup>
    <MSBuild
      Projects="@(AotProject)"
      Targets="AotCompile"
      Condition="@(AllDlls->Count()) &gt; 0"
      BuildInParallel="true"
      />
  </Target>

  <UsingTask TaskName="AndroidAppBuilderTask" AssemblyFile="$(AndroidAppBuilderTasksAssemblyPath)" Condition="'$(RunWithAndroid)'=='true'"/>

  <Target Name="BuildAndroidApp">

    <PropertyGroup>
      <RuntimeIdentifier>android-$(TargetArchitecture)</RuntimeIdentifier>
      <CMDDIR_Grandparent>$([System.IO.Path]::GetDirectoryName($([System.IO.Path]::GetDirectoryName($(_CMDDIR)))))</CMDDIR_Grandparent>
      <CategoryWithSlash>$([System.String]::Copy('$(_CMDDIR)').Replace("$(CMDDIR_Grandparent)/",""))</CategoryWithSlash>
      <Category>$([System.String]::Copy('$(CategoryWithSlash)').Replace('/','_'))</Category>
      <BuildDir>$(IntermediateOutputPath)\AndroidApps\$(Category)</BuildDir>
      <AppDir>$(BuildDir)\apk</AppDir>
      <FinalApkPath>$(XUnitTestBinBase)$(CategoryWithSlash)\$(Category).apk</FinalApkPath>
      <StripDebugSymbols>False</StripDebugSymbols>
      <DiagnosticPorts>127.0.0.1:9000,nosuspend,listen</DiagnosticPorts>
      <StripDebugSymbols Condition="'$(Configuration)' == 'Release'">True</StripDebugSymbols>
      <MicrosoftNetCoreAppRuntimePackDir>$(ArtifactsBinDir)microsoft.netcore.app.runtime.android-$(TargetArchitecture)\$(Configuration)\runtimes\android-$(TargetArchitecture)\</MicrosoftNetCoreAppRuntimePackDir>
      <AndroidAbi Condition="'$(TargetArchitecture)' == 'arm64'">arm64-v8a</AndroidAbi>
      <AndroidAbi Condition="'$(TargetArchitecture)' == 'arm'">armeabi-v7a</AndroidAbi>
      <AndroidAbi Condition="'$(TargetArchitecture)' == 'x64'">x86_64</AndroidAbi>
      <AndroidAbi Condition="'$(TargetArchitecture)' == 'x86'">x86</AndroidAbi>
      <MonoInterp>false</MonoInterp>
      <MonoInterp Condition="'$(RuntimeVariant)' == 'monointerpreter'">true</MonoInterp>
    </PropertyGroup>

    <ItemGroup>
      <RuntimeComponents Include="diagnostics_tracing" />
      <RuntimeComponents Include="marshal-ilgen" />
    </ItemGroup>

    <RemoveDir Directories="$(AppDir)" />
    <MakeDir Directories="$(BuildDir)"/>

    <ItemGroup>
      <AllCMDsPresent Include="$(_CMDDIR)\**\*.$(TestScriptExtension)" Exclude="$(_CMDDIR)\**\AppBundle\*.$(TestScriptExtension)" />
      <TestAssemblies Include="@(AllCMDsPresent->'%(RelativeDir)%(Filename).dll')" />
      <TestAssemblyDirs Include="@(AllCMDsPresent->'%(RelativeDir)')" />
      <AssembliesInTestDirs Include="%(AllCMDsPresent.RelativeDir)*.dll" Exclude="@(TestAssemblies)"/>
      <RuntimePackLibs Include="$(MicrosoftNetCoreAppRuntimePackDir)lib/**/*.dll" />
      <RuntimePackNativeLibs Include="$(MicrosoftNetCoreAppRuntimePackDir)native/**/*.dll;$(MicrosoftNetCoreAppRuntimePackDir)native/**/*.a;$(MicrosoftNetCoreAppRuntimePackDir)native/**/*.so;$(MicrosoftNetCoreAppRuntimePackDir)native/**/*.dex;$(MicrosoftNetCoreAppRuntimePackDir)native/**/*.jar" />
      <TestTargetingPathLibs Include="$(TargetingPackPath)/*.dll" />
    </ItemGroup>

    <Copy
        SourceFiles="@(TestAssemblies)"
        DestinationFolder="$(BuildDir)" />

    <Copy
        SourceFiles="@(AssembliesInTestDirs)"
        DestinationFolder="$(BuildDir)" />

    <Copy
        SourceFiles="@(RuntimePackNativeLibs)"
        DestinationFolder="$(BuildDir)" />

    <Copy
        SourceFiles="@(RuntimePackLibs)"
        DestinationFolder="$(BuildDir)" />

    <Copy
        SourceFiles="@(TestTargetingPathLibs)"
        DestinationFolder="$(BuildDir)" />

    <AndroidAppBuilderTask
        AppDir="$(BuildDir)"
        DiagnosticPorts="$(DiagnosticPorts)"
        ForceInterpreter="$(MonoInterp)"
        MonoRuntimeHeaders="$(MicrosoftNetCoreAppRuntimePackDir)/native/include/mono-2.0"
        OutputDir="$(AppDir)"
        ProjectName="$(Category)"
        RuntimeComponents="@(RuntimeComponents)"
        RuntimeIdentifier="$(RuntimeIdentifier)"
        StripDebugSymbols="$(StripDebugSymbols)">
        <Output TaskParameter="ApkBundlePath" PropertyName="ApkBundlePath" />
        <Output TaskParameter="ApkPackageId" PropertyName="ApkPackageId" />
    </AndroidAppBuilderTask>
    <Move SourceFiles="$(ApkBundlePath)" DestinationFiles="$(FinalApkPath)" />
    <Message Importance="High" Text="Apk:        $(FinalApkPath)"/>
    <Message Importance="High" Text="PackageId:  $(ApkPackageId)"/>
    <Message Importance="High" Text="MonoInterp: $(MonoInterp)"/>
    <!-- delete the BuildDir in CI builds to save disk space on build agents since they're no longer needed -->
    <RemoveDir Condition="'$(ContinuousIntegrationBuild)' == 'true'" Directories="$(BuildDir)" />
  </Target>

  <Target Name="BuildAllAndroidApp" DependsOnTargets="GetListOfTestCmds;FindCmdDirectories">
    <MSBuild
      Projects="$(MSBuildProjectFile)"
      Targets="BuildAndroidApp"
      Properties="_CMDDIR=%(TestDirectories.Identity)"
      Condition="'@(TestDirectories)' != ''" />
  </Target>

  <UsingTask TaskName="AppleAppBuilderTask" AssemblyFile="$(AppleAppBuilderTasksAssemblyPath)" />
  <UsingTask TaskName="MonoAOTCompiler" AssemblyFile="$(MonoAOTCompilerTasksAssemblyPath)" />

  <Target Name="BuildMonoiOSApp">
    <PropertyGroup>
      <IntermediateOutputPath>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)'))</IntermediateOutputPath>
      <CMDDIR_Grandparent>$([System.IO.Path]::GetDirectoryName($([System.IO.Path]::GetDirectoryName($(_CMDDIR)))))</CMDDIR_Grandparent>
      <CategoryWithSlash>$([System.String]::Copy('$(_CMDDIR)').Replace("$(CMDDIR_Grandparent)/",""))</CategoryWithSlash>
      <Category>$([System.String]::Copy('$(CategoryWithSlash)').Replace('/','_'))</Category>
      <XUnitWrapperFileName>$([System.String]::Copy('$(CategoryWithSlash)').Replace('/', '.')).XUnitWrapper.dll</XUnitWrapperFileName>
      <XUnitWrapperDll>$(CMDDIR_GrandParent)/$(CategoryWithSlash)/$(XUnitWrapperFileName)</XUnitWrapperDll>
      <BuildDir>$(IntermediateOutputPath)\iOSApps\$(Category)</BuildDir>
      <FinalPath>$(XUnitTestBinBase)$(CategoryWithSlash)\$(Category).app</FinalPath>
      <_MobileIntermediateOutputPath>$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'mobile'))</_MobileIntermediateOutputPath>
    </PropertyGroup>

    <PropertyGroup>
      <AssemblyName>$(Category)</AssemblyName>
      <RuntimePackOSSuffix Condition="'$(TargetOS)' == 'iossimulator'" >iossimulator</RuntimePackOSSuffix>
      <RuntimePackOSSuffix Condition="'$(TargetOS)' == 'ios'" >ios</RuntimePackOSSuffix>
      <RuntimePackOSSuffix Condition="'$(TargetOS)' == 'tvossimulator'" >tvossimulator</RuntimePackOSSuffix>
      <RuntimePackOSSuffix Condition="'$(TargetOS)' == 'tvos'" >tvos</RuntimePackOSSuffix>
      <RuntimePackOSSuffix Condition="'$(TargetOS)' == 'maccatalyst'" >maccatalyst</RuntimePackOSSuffix>

      <MicrosoftNetCoreAppRuntimePackDir>$(ArtifactsBinDir)microsoft.netcore.app.runtime.$(RuntimePackOSSuffix)-$(TargetArchitecture)/$(Configuration)/runtimes/$(RuntimePackOSSuffix)-$(TargetArchitecture)</MicrosoftNetCoreAppRuntimePackDir>
      <MicrosoftNetCoreAppRuntimePackNativeDir>$(MicrosoftNetCoreAppRuntimePackDir)/native</MicrosoftNetCoreAppRuntimePackNativeDir>

      <BundleDir>$([MSBuild]::NormalizeDirectory('$(BuildDir)', 'AppBundle'))</BundleDir>
    </PropertyGroup>
    <ItemGroup>
      <AllTestScripts Include="$(_CMDDIR)\**\*.sh" Exclude="$(_CMDDIR)\**\AppBundle\*.sh" />
      <TestExclusions Include="@(ExcludeList->Metadata('FullPath'))" Condition="$(HaveExcludes)" />
      <TestScripts Include="@(AllTestScripts)" Exclude="@(TestExclusions)" />
      <TestDllPaths Include="$([System.IO.Path]::ChangeExtension('%(TestScripts.Identity)', 'dll'))" />
      <TestDlls Include="%(TestDllPaths.Identity)" Condition="Exists(%(TestDllPaths.Identity))" />
      <RuntimePackLibs Include="$(MicrosoftNetCoreAppRuntimePackDir)lib/**/*.dll" />
      <RuntimePackNativeLibs Include="$(MicrosoftNetCoreAppRuntimePackDir)/**/*.dll;$(MicrosoftNetCoreAppRuntimePackDir)/native/**/*.a;$(MicrosoftNetCoreAppRuntimePackDir)/native/**/*.dylib;" />
      <EntryPoints Include="testdir-%(TestDlls.Filename)/%(TestDlls.Filename).dll" />
      <ExtraDlls Include="%(TestDlls.RelativeDir)*.dll" Exclude="@(TestDlls)">
        <TestDllFilename>@(TestDlls->'%(Filename)')</TestDllFilename>
      </ExtraDlls>
      <TestTargetingPathLibs Include="$(TargetingPackPath)/*.dll" />
    </ItemGroup>

    <RemoveDir Directories="$(BundleDir)" />
    <RemoveDir Directories="$(BuildDir)" />

    <MakeDir Directories="$(BuildDir)" />
    <MakeDir Directories="$(BuildDir)/testdir-%(TestDlls.Filename)" />

    <Copy
        SourceFiles="@(RuntimePackNativeLibs)"
        DestinationFolder="$(BuildDir)" />
    <Copy
        SourceFiles="@(RuntimePackLibs)"
        DestinationFolder="$(BuildDir)" />
    <Copy
        SourceFiles="@(TestTargetingPathLibs)"
        DestinationFolder="$(BuildDir)" />
    <Copy
        SourceFiles="%(TestDlls.Identity)"
        DestinationFolder="$(BuildDir)/testdir-%(TestDlls.Filename)" />
    <Copy
        SourceFiles="%(ExtraDlls.Identity)"
        DestinationFolder="$(BuildDir)/testdir-%(ExtraDlls.TestDllFilename)" />

    <MakeDir Directories="$(_MobileIntermediateOutputPath)" />

    <PropertyGroup>
      <PublishDir>$(BuildDir)/</PublishDir>
      <TestProjectName>$(AssemblyName)</TestProjectName>
      <IgnoreForCI Condition="@(TestDlls->Count()) == 0">true</IgnoreForCI>
      <UseRuntimeComponents>true</UseRuntimeComponents>
      <IncludesTestRunner>false</IncludesTestRunner>
    </PropertyGroup>

    <UpdateRunScriptToHandleMultipleEntryPoints EntryPoints="@(EntryPoints)" RunScriptCommand="$(RunScriptCommand)" AppName="$(Category)" Condition="'$(BuildTestsOnHelix)' == 'true'">
      <Output TaskParameter="OutputScript" PropertyName="RunScriptCommand" />
    </UpdateRunScriptToHandleMultipleEntryPoints>
  </Target>

  <UsingTask
    TaskName="UpdateRunScriptToHandleMultipleEntryPoints"
    TaskFactory="RoslynCodeTaskFactory"
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
  <ParameterGroup>
    <EntryPoints ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
    <RunScriptCommand ParameterType="System.String" Required="true" />
    <AppName ParameterType="System.String" Required="true" />
    <OutputScript ParameterType="System.String" Output="true" />
  </ParameterGroup>
  <Task>
    <Using Namespace="System"/>
    <Using Namespace="Microsoft.Build.Framework"/>
    <Using Namespace="Microsoft.Build.Utilities"/>
    <Using Namespace="System.Linq"/>
    <Using Namespace="System.Text"/>

    <!-- 
      This code fragment updates the default run script for Helix. 
      With the library tests, there is a single entry point provided as MainLibraryFileName. With the runtime tests, a bundle may have multiple main entry points. The code makes the following changes:
      - For each main entry point, it adds the mlaunch environment parameters MONO_APPLE_APP_ENTRY_POINT_LIB_NAME and MONO_APPLE_APP_ASSEMBLY_LOAD_PREFIX
      - After each execution, it renames the log file to match the MONO_APPLE_APP_ENTRY_POINT_LIB_NAME entry point
     -->
    <Code Type="Fragment" Language="cs">
      <![CDATA[
        string[] lines = RunScriptCommand.Split('\n');
        string lastLine = lines[lines.Length - 1];
        StringBuilder resultBuilder = new StringBuilder();

        // Iterate over each entry point and modify the run script
        foreach (ITaskItem item in EntryPoints)
        {
            string value = item.ItemSpec;
            
            // Add the MONO_APPLE_APP_ENTRY_POINT_LIB_NAME and MONO_APPLE_APP_ASSEMBLY_LOAD_PREFIX environment parameters to the run script
            string output = lastLine.Replace("apple test", "apple run").Replace("--signal-app-end", $"--expected-exit-code=100 --set-env=MONO_APPLE_APP_ENTRY_POINT_LIB_NAME={value} --set-env=MONO_APPLE_APP_ASSEMBLY_LOAD_PREFIX={value.Split('/')[0]}") + "&& echo \"Test passed\" || { echo \"Test failed\"; exit 1; }";
            resultBuilder.AppendLine(output);

            // Rename the log file to match the MONO_APPLE_APP_ENTRY_POINT_LIB_NAME
            resultBuilder.AppendLine("mv \"${output_directory}/net.dot."+AppName+".log\" \"${output_directory}/"+value.Split('/')[0]+".log\"");
        }

        StringBuilder outputScriptBuilder = new StringBuilder(string.Join("\n", lines.Take(lines.Length - 1)));
        outputScriptBuilder.AppendLine();
        outputScriptBuilder.Append(resultBuilder.ToString());

        OutputScript = outputScriptBuilder.ToString();
      ]]>
    </Code>
  </Task>
</UsingTask>

  <!-- This target builds a Native AOT iOS App -->
  <Target Name="BuildNativeAOTiOSApp" DependsOnTargets="SetupOSSpecificProps">
    <PropertyGroup>
      <CategoryPath>$([System.IO.Path]::GetDirectoryName($([System.IO.Path]::GetDirectoryName($(_CMDDIR)))))</CategoryPath>
      <CategoryName>$([System.IO.Path]::GetFileName($(CategoryPath)))</CategoryName>
      <TestRelativePath>$(CategoryName)/$([System.String]::Copy('$(_CMDDIR)').Replace("$(CategoryPath)/",""))</TestRelativePath>
      <TestName>$([System.IO.Path]::GetFileName($(_CMDDIR)))</TestName>
      <AppName>$([System.String]::Copy('$(TestRelativePath)').Replace('/','_'))</AppName>
      <AppleBuildDir>$(IntermediateOutputPath)\iOSApps\$(AppName)</AppleBuildDir>
      <FinalPath>$(XUnitTestBinBase)$(TestRelativePath)\$(AppName).app</FinalPath>
    </PropertyGroup>

    <PropertyGroup>
      <DevTeamProvisioning>-</DevTeamProvisioning>
      <AppleGenerateAppBundle>true</AppleGenerateAppBundle>
      <GenerateXcodeProject>true</GenerateXcodeProject>
      <AppleBundleDir>$(AppDir)</AppleBundleDir>
      <RunAOTCompilation>false</RunAOTCompilation>
      <MonoForceInterpreter>false</MonoForceInterpreter>
    </PropertyGroup>

    <ItemGroup>
      <NativeDependencies Include="$(IntermediateOutputPath)\..\$(TestRelativePath)\$(TestName)\native\$(TestName).o" />
    </ItemGroup>

    <ItemGroup>
      <_LinkerFlagsToDrop Include="@(NativeFramework->'-framework %(Identity)')" />
      <LinkerArg Remove="@(_LinkerFlagsToDrop)" />
      <ExtraAppLinkerArgs Include="@(LinkerArg)" />
    </ItemGroup>

    <RemoveDir Directories="$(AppleBuildDir)" />
    <RemoveDir Directories="$(AppDir)" />
    <MakeDir Directories="$(AppleBuildDir)" />

    <Copy
        SourceFiles="@(GlobalizationNativeLibs)"
        DestinationFolder="$(AppleBuildDir)" />
  </Target>

  <!-- This target moves app bundles to the payload directory -->
  <Target Name="AfterAppleBuild">
    <!-- Apparently MSBuild cannot move directories and recursively copying a
         a directory requires writing some sort of recursive traversal
         logic yourself. -->
    <ItemGroup>
      <RecursiveCopyHack Include="$(AppBundlePath)/**/*.*" />
    </ItemGroup>
    <MakeDir Directories="$(FinalPath)" />
    <Copy SourceFiles="@(RecursiveCopyHack)" DestinationFolder="$(FinalPath)/%(RecursiveDir)" />
    <RemoveDir Directories="$(AppBundlePath)" />
    <Message Importance="High" Text="Final app: $(FinalPath)" />
  </Target>

  <Target Name="BuildAlliOSApp" DependsOnTargets="GetListOfTestCmds;FindCmdDirectories">
    <ItemGroup>
      <RunProj Include="$(MSBuildProjectFile)">
        <Properties>_CMDDIR=%(TestDirectories.Identity)</Properties>
      </RunProj>
    </ItemGroup>
    <MSBuild
      Projects="@(RunProj)"
      Targets="BuildMonoiOSApp"
      BuildInParallel="true"
      Condition="'@(TestDirectories)' != '' and '$(TestBuildMode)' != 'nativeaot'"
    />

    <MSBuild
      Projects="@(RunProj)"
      Targets="BuildNativeAOTiOSApp;_AppleGenerateAppBundle;AfterAppleBuild"
      BuildInParallel="true"
      Condition="'@(TestDirectories)' != '' and '$(TestBuildMode)' == 'nativeaot'"
    />
  </Target>

  <Target Name="GetListOfTestCmds">
    <ItemGroup>
      <SkipTestDirsPaths Include="$([System.IO.Path]::GetFullPath('$(XunitTestBinBase)%(DisabledTestDir.Identity)'))" />
      <AllRunnableTestPaths Include="$(XunitTestBinBase)\**\*.$(TestScriptExtension)"/>
      <AllRunnableTestPaths Remove="$(XunitTestBinBase)\**\run-v8.sh" Condition="'$(TargetArchitecture)' == 'wasm'" />
      <AllRunnableTestPaths Remove="%(SkipTestDirsPaths.Identity)\**\*.$(TestScriptExtension)" />
      <MergedAssemblyMarkerPaths Include="$(XunitTestBinBase)\**\*.MergedTestAssembly"/>
      <MergedAssemblyFolders Include="$([System.IO.Path]::GetDirectoryName('%(MergedAssemblyMarkerPaths.Identity)'))" />
      <MergedAssemblyParentFolders Include="$([System.IO.Path]::GetDirectoryName('%(MergedAssemblyFolders.Identity)'))" />
      <AllRunnableTestPaths Remove="%(MergedAssemblyParentFolders.Identity)\**\*.$(TestScriptExtension)" Condition="'@(MergedAssemblyParentFolders)' != '' and '$(TargetsAppleMobile)' != 'true'" />
      <MergedRunnableTestPaths Include="$([System.IO.Path]::ChangeExtension('%(MergedAssemblyMarkerPaths.Identity)', '.$(TestScriptExtension)'))" Condition="'@(MergedAssemblyMarkerPaths)' != ''" />
      <OutOfProcessTestMarkerPaths Include="$(XunitTestBinBase)\**\*.OutOfProcessTest"/>
      <OutOfProcessTestPaths Include="$([System.IO.Path]::ChangeExtension('%(OutOfProcessTestMarkerPaths.Identity)', '.$(TestScriptExtension)'))" Condition="'@(OutOfProcessTestMarkerPaths)' != ''" />
      <NoMonoAotMarkerPaths Include="$(XunitTestBinBase)\**\*.NoMonoAot" />
      <NoMonoAotAssemblyPaths Include="$([System.IO.Path]::ChangeExtension('%(NoMonoAotMarkerPaths.Identity)', '.dll'))" Condition="'@(NoMonoAotMarkerPaths)' != ''" />
    </ItemGroup>
    <!-- Remove the cmd/sh scripts for merged test runner app bundles from our list. -->
    <PropertyGroup Condition="'$(TargetsMobile)' == 'true'">
      <MergedRunnableTestAppBundleScriptPathsPattern>@(MergedAssemblyMarkerPaths->'%(RootDir)%(Directory)AppBundle/**/*.$(TestScriptExtension)')</MergedRunnableTestAppBundleScriptPathsPattern>
    </PropertyGroup>
    <ItemGroup>
      <LegacyRunnableTestPaths Include="@(AllRunnableTestPaths)" Exclude="@(MergedRunnableTestPaths);@(OutOfProcessTestPaths);$(MergedRunnableTestAppBundleScriptPathsPattern)" />
      <LegacyRunnableTestPaths Condition="'$(TargetsAppleMobile)' == 'true'" Include="@(MergedRunnableTestPaths)" />
    </ItemGroup>
  </Target>

  <Import Project="$(RepoRoot)/src/tests/Common/tests.targets" />
  <Import Project="$(RepoRoot)/src/tests/Common/publishdependency.targets" />

  <Target Name="CreateTestOverlay" DependsOnTargets="CopyDependencyToCoreRoot" />

  <Target Name="Clean">
    <RemoveDir Condition=" '$(BuildWrappers)'=='true'" Directories="$(MSBuildThisFileDirectory)../$(XunitWrapperGeneratedCSDirBase);" ContinueOnError="WarnAndContinue" />
  </Target>

  <Target Name="TestBuild" DependsOnTargets="@(TestBuildSteps)" />

  <Target Name="BuildTargetingPack" AfterTargets="BatchRestorePackages">
    <Message Text="$(MsgPrefix)Building Targeting Pack" Importance="High" />
    <MSBuild Projects="Common\external\external.csproj"
             Targets="Build" />
  </Target>

  <Target Name="BatchRestorePackages">
    <Message Importance="High" Text="[$([System.DateTime]::Now.ToString('HH:mm:ss.ff'))] Restoring all packages..." />

    <!-- restore all csproj's with PackageReferences in one pass -->
    <MSBuild Projects="build.proj"
             Properties="RestoreProj=%(RestoreProjects.Identity)"
             Targets="RestorePackage" />

    <Message Importance="High" Text="[$([System.DateTime]::Now.ToString('HH:mm:ss.ff'))] Restoring all packages...Done." />
  </Target>

  <Target Name="RestorePackage">
    <PropertyGroup>
      <_ConfigurationProperties>/p:TargetOS=$(TargetOS) /p:TargetArchitecture=$(TargetArchitecture) /p:Configuration=$(Configuration) /p:CrossBuild=$(CrossBuild)</_ConfigurationProperties>
      <_ConfigurationProperties Condition="'$(UseLocalAppHostPack)' == 'true'">$(_ConfigurationProperties) -p:EnableAppHostPackDownload=false -p:EnableTargetingPackDownload=false -p:EnableRuntimePackDownload=false</_ConfigurationProperties>
      <DotnetRestoreCommand>"$(DotNetTool)" restore $(RestoreProj) $(PackageVersionArg) /p:SetTFMForRestore=true $(_ConfigurationProperties)</DotnetRestoreCommand>
    </PropertyGroup>
    <Exec Command="$(DotnetRestoreCommand)"/>
  </Target>

  <!-- Override RestorePackages from dir.traversal.targets and do a batch restore -->
  <Target Name="RestorePackages"
      DependsOnTargets="BatchRestorePackages"
      Condition="'$(__SkipRestorePackages)' != '1'" />

  <Target Name="ManagedBuild"
      DependsOnTargets="BuildManagedTestGroups"
      Condition="'$(__BuildTestWrappersOnly)' != '1' and '$(__GenerateLayoutOnly)' != '1' and '$(__SkipManaged)' != '1' and !$(MonoAot) and !$(MonoFullAot)" />

  <Target Name="BuildManagedTestGroups" DependsOnTargets="RestorePackages;ResolveDisabledProjects;BuildNativeAotFrameworkObjects">
    <Message Importance="High" Text="$(MsgPrefix)Building managed test components" />
    <!-- Execute msbuild test build in stages - workaround for excessive data retention in MSBuild ConfigCache -->
    <!-- See https://github.com/Microsoft/msbuild/issues/2993 -->

    <!-- We need to build group #1 manually as it doesn't have a _GroupStartsWith item associated with it, see the comment in Common\dirs.proj -->
    <MSBuild Projects="$(MSBuildThisFileFullPath)" Targets="BuildManagedTestGroup" Properties="__TestGroupToBuild=1;__SkipRestorePackages=1" />
    <MSBuild Projects="$(MSBuildThisFileFullPath)" Targets="BuildManagedTestGroup" Properties="__TestGroupToBuild=%(_GroupStartsWith.GroupNumber);__SkipRestorePackages=1" />
  </Target>

  <Target Name="BuildManagedTestGroup"
      DependsOnTargets="ResolveDisabledProjects"
      Condition="'$(__SkipManaged)' != '1'" >

    <PropertyGroup>
      <TargetToBuild>Build</TargetToBuild>
      <!-- In split pipeline mode (in the lab) we're using the native component copying step to generate the test execution scripts -->
      <TargetToBuild Condition="'$(__CopyNativeTestBinaries)' == '1'">CopyAllNativeTestProjectBinaries</TargetToBuild>

      <GroupBuildCmd>$(DotNetCli) msbuild</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) $(MSBuildThisFileFullPath)</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) /t:$(TargetToBuild)</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:TargetArchitecture=$(TargetArchitecture)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:Configuration=$(Configuration)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:LibrariesConfiguration=$(LibrariesConfiguration)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:TasksConfiguration=$(TasksConfiguration)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:TargetOS=$(TargetOS)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:ToolsOS=$(ToolsOS)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:PackageOS=$(PackageOS)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:RuntimeFlavor=$(RuntimeFlavor)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:RuntimeVariant=$(RuntimeVariant)"</GroupBuildCmd>
      <GroupBuildCmd Condition="'$(ServerGarbageCollection)' != ''">$(GroupBuildCmd) "/p:ServerGarbageCollection=$(ServerGarbageCollection)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:CLRTestBuildAllTargets=$(CLRTestBuildAllTargets)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:UseCodeFlowEnforcement=$(UseCodeFlowEnforcement)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:__TestGroupToBuild=$(__TestGroupToBuild)"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) "/p:__SkipRestorePackages=1"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) /nodeReuse:false</GroupBuildCmd>
      <GroupBuildCmd Condition="'$(TargetOS)' != 'browser' or '$(ContinuousIntegrationBuild)' != 'true'">$(GroupBuildCmd) /maxcpucount</GroupBuildCmd>
      <!-- https://github.com/dotnet/runtime/issues/93134 -->
      <GroupBuildCmd Condition="'$(TargetOS)' == 'browser' and '$(ContinuousIntegrationBuild)' == 'true'">$(GroupBuildCmd) /m:1</GroupBuildCmd>
      <GroupBuildCmd Condition="'$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvos'">$(GroupBuildCmd) "/p:DevTeamProvisioning=-"</GroupBuildCmd>
      <GroupBuildCmd>$(GroupBuildCmd) /bl:$(ArtifactsDir)/log/$(Configuration)/InnerManagedTestBuild.$(__TestGroupToBuild).binlog</GroupBuildCmd>
      <GroupBuildCmd Condition="'$(CrossBuild)' == 'true'">$(GroupBuildCmd) "/p:CrossBuild=true"</GroupBuildCmd>
      <GroupBuildCmd Condition="'$(TestBuildMode)' == 'nativeaot'">$(GroupBuildCmd) "/p:DefaultBuildAllTarget=BuildNativeAot"</GroupBuildCmd>
      <GroupBuildCmd Condition="'$(IlcMultiModule)' == 'true'">$(GroupBuildCmd) "/p:IlcMultiModule=true"</GroupBuildCmd>
      <GroupBuildCmd Condition="'$(IlcUseServerGc)' == 'false'">$(GroupBuildCmd) "/p:IlcUseServerGc=false"</GroupBuildCmd>
      <GroupBuildCmd Condition="'$(BuildNativeAotFrameworkObjects)' == 'true'">$(GroupBuildCmd) "/p:BuildNativeAotFrameworkObjects=true"</GroupBuildCmd>
    </PropertyGroup>

    <Message Importance="High" Text="$(MsgPrefix)Building managed test group $(__TestGroupToBuild): $(GroupBuildCmd)" />

    <Exec Command="$(GroupBuildCmd)" />
  </Target>

  <Target Name="CheckTestBuildStep"
      DependsOnTargets="CheckTestBuild"
      Condition="'$(__BuildTestWrappersOnly)' != '1' and '$(__GenerateLayoutOnly)' != '1' and '$(__CopyNativeTestBinaries)' != '1' and !$(MonoAot) and !$(MonoFullAot)" />

  <Target Name="GenerateLayout"
      DependsOnTargets="CreateTestOverlay"
      AfterTargets="ManagedBuild;RestorePackages"
      Condition="'$(__BuildTestWrappersOnly)' != '1' and '$(__CopyNativeTestBinaries)' != '1' and '$(__SkipGenerateLayout)' != '1' and !$(MonoAot) and !$(MonoFullAot)">

    <MSBuild
      Projects="$(MSBuildProjectFile)"
      Targets="EmitTestExclusionList"
      Properties="XunitTestBinBase=$(XunitTestBinBase)" />

    <MSBuild
      Projects="Common\XUnitLogChecker\XUnitLogChecker.csproj"
      Targets="Build" />
  </Target>

  <Target Name="BuildTestWrappers"
      DependsOnTargets="CreateAllWrappers"
      AfterTargets="ManagedBuild;RestorePackages"
      Condition="'$(__GenerateLayoutOnly)' != '1' and '$(__CopyNativeTestBinaries)' != '1' and !$(MonoAot) and !$(MonoFullAot) and ('$(__BuildTestWrappersOnly)' == '1' or ('$(__SkipTestWrappers)' != '1' and '$(__SkipManaged)' != '1'))" />

  <Target Name="CrossgenFramework"
      DependsOnTargets="GenerateLayout"
      Condition="'$(__BuildTestWrappersOnly)' != '1' and '$(__CopyNativeTestBinaries)' != '1' and '$(__TestBuildMode)' == 'crossgen2' and !$(MonoAot) and !$(MonoFullAot)" >

    <PropertyGroup>
      <CrossgenDir>$(__BinDir)\$(BuildArchitecture)</CrossgenDir>

      <CrossgenOutputDir>$(__TestIntermediatesDir)\crossgen.out</CrossgenOutputDir>

      <CrossgenCmd>$(DotNetCli)</CrossgenCmd>
      <CrossgenCmd>$(CrossgenCmd) "$(CORE_ROOT)\R2RTest\R2RTest.dll"</CrossgenCmd>
      <CrossgenCmd>$(CrossgenCmd) compile-framework</CrossgenCmd>
      <CrossgenCmd>$(CrossgenCmd) -cr "$(CORE_ROOT)"</CrossgenCmd>
      <CrossgenCmd>$(CrossgenCmd) --output-directory "$(CrossgenOutputDir)"</CrossgenCmd>
      <CrossgenCmd>$(CrossgenCmd) --release</CrossgenCmd>
      <CrossgenCmd>$(CrossgenCmd) --nocleanup</CrossgenCmd>
      <CrossgenCmd>$(CrossgenCmd) --target-arch $(TargetArchitecture)</CrossgenCmd>
      <CrossgenCmd>$(CrossgenCmd) -dop $(NUMBER_OF_PROCESSORS)</CrossgenCmd>
      <CrossgenCmd>$(CrossgenCmd) -m "$(CORE_ROOT)\StandardOptimizationData.mibc"</CrossgenCmd>

      <CrossgenCmd Condition="'$(__CreatePdb)' != ''">$(CrossgenCmd) --pdb</CrossgenCmd>
      <CrossgenCmd Condition="'$(__CreatePerfmap)' != ''">$(CrossgenCmd) --perfmap --perfmap-format-version 1</CrossgenCmd>
      <CrossgenCmd Condition="'$(__CompositeBuildMode)' != ''">$(CrossgenCmd) --composite</CrossgenCmd>
      <CrossgenCmd Condition="'$(__CompositeBuildMode)' == ''">$(CrossgenCmd) --crossgen2-parallelism 1</CrossgenCmd>

      <CrossgenCmd>$(CrossgenCmd) --verify-type-and-field-layout</CrossgenCmd>
      <CrossgenCmd>$(CrossgenCmd) --crossgen2-path "$(CrossgenDir)\crossgen2\tools\crossgen2.dll"</CrossgenCmd>
    </PropertyGroup>

    <Message Importance="High" Text="$(MsgPrefix)Compiling framework using Crossgen2: $(CrossgenCmd)" />
    <Exec Command="$(CrossgenCmd)" />

    <ItemGroup>
      <CrossgenOutputFiles Include="$(CrossgenOutputDir)\*.dll" />
      <CrossgenOutputFiles Include="$(CrossgenOutputDir)\*.ni.pdb" Condition="'$(__CreatePdb)' != ''" />
      <CrossgenOutputFiles Include="$(CrossgenOutputDir)\*.ni.r2rmap" Condition="'$(__CreatePerfmap)' != ''" />
    </ItemGroup>

    <Move SourceFiles="@(CrossgenOutputFiles)" DestinationFolder="$(CORE_ROOT)" />
  </Target>

  <Target Name="CreateAndroidApps"
      DependsOnTargets="BuildAllAndroidApp"
      AfterTargets="ManagedBuild"
      Condition="'$(__BuildTestWrappersOnly)' != '1' and '$(__GenerateLayoutOnly)' != '1' and '$(__CopyNativeTestBinaries)' != '1' and $(RunWithAndroid)" />

  <Target Name="CreateIosApps"
      DependsOnTargets="BuildAlliOSApp"
      AfterTargets="ManagedBuild"
      Condition="'$(__BuildTestWrappersOnly)' != '1' and '$(__GenerateLayoutOnly)' != '1' and '$(__CopyNativeTestBinaries)' != '1' and '$(RunWithiOS)' == 'true'" />

  <Target Name="BuildMonoAot"
      DependsOnTargets="MonoAotCompileTests"
      AfterTargets="ManagedBuild"
      Condition="'$(__BuildTestWrappersOnly)' != '1' and '$(__GenerateLayoutOnly)' != '1' and '$(__CopyNativeTestBinaries)' != '1' and ($(MonoAot) or $(MonoFullAot))" />

  <Target Name="BuildNativeAotFrameworkObjects"
          Condition="'$(BuildNativeAotFrameworkObjects)' == 'true' and '$(TestBuildMode)' == 'nativeaot'">
    <ItemGroup>
      <CreateLibProperty Include="IlcToolsPath=$(IlcToolsPath)" />
      <CreateLibProperty Include="IlcBuildTasksPath=$(IlcBuildTasksPath)" />
      <CreateLibProperty Include="IlcSdkPath=$(IlcSdkPath)" />
      <CreateLibProperty Include="IlcFrameworkPath=$(IlcFrameworkPath)" />
      <CreateLibProperty Include="IlcFrameworkNativePath=$(IlcFrameworkNativePath)" />
      <CreateLibProperty Include="IlcDynamicBuildPropertyDependencies=$(IlcDynamicBuildPropertyDependencies)" />
      <CreateLibProperty Include="FrameworkLibPath=$(IlcSdkPath)" />
      <CreateLibProperty Include="FrameworkObjPath=$(IntermediateOutputPath)/NativeAOTFX" />
      <CreateLibProperty Condition="'$(Configuration)' == 'Checked' or '$(Configuration)' == 'Release'" Include="Optimize=true" />
      <CreateLibProperty Include="NETCoreSdkVersion=6.0.0" />
    </ItemGroup>
    <MSBuild Projects="$(CoreCLRBuildIntegrationDir)/BuildFrameworkNativeObjects.proj"
      Targets="CreateLib"
      Properties="@(CreateLibProperty)" />
  </Target>

  <Target Name="EmitTestExclusionList" DependsOnTargets="GetFilteredExcludeList">
    <PropertyGroup>
      <TestExclusionListPath>$(CORE_ROOT)\TestExclusionList.txt</TestExclusionListPath>
    </PropertyGroup>

    <WriteLinesToFile
        File="$(TestExclusionListPath)"
        Lines="@(FilteredExcludeList)"
        Overwrite="true"
        Encoding="Unicode" />
  </Target>
</Project>
